package com.a.lib_base.base.viewmodel

import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import com.a.lib_network.bean.HttpData
import com.a.lib_utils.TipUtil
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch

/**
 * Create by KunMinX at 2022/7/3
 */
open class MviDispatcherKTX<Event> : BaseOwnerViewModel() {
    private var _sharedFlow: MutableSharedFlow<Event>? = null
    private val delayMap: MutableMap<Int, Boolean> = mutableMapOf()

    private fun initQueue() {
        if (_sharedFlow == null) _sharedFlow = MutableSharedFlow(
            onBufferOverflow = BufferOverflow.DROP_OLDEST,
            extraBufferCapacity = initQueueMaxLength()
        )
    }

    protected open fun initQueueMaxLength(): Int {
        return DEFAULT_QUEUE_LENGTH
    }

    fun output(activity: AppCompatActivity?, observer: (Event) -> Unit) {
        initQueue()
        delayMap[System.identityHashCode(activity)] = true
        activity?.lifecycleScope?.launch {
            activity.repeatOnLifecycle(Lifecycle.State.STARTED) {
                delayMap.remove(System.identityHashCode(activity))
                _sharedFlow?.collect { observer.invoke(it) }
            }
        }
    }

    fun output(fragment: Fragment?, observer: (Event) -> Unit) {
        initQueue()
        delayMap[System.identityHashCode(fragment)] = true
        fragment?.viewLifecycleOwner?.lifecycleScope?.launch {
            fragment.viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                delayMap.remove(System.identityHashCode(fragment))
                _sharedFlow?.collect { observer.invoke(it) }
            }
        }
    }

    protected suspend fun sendResult(event: Event) {
        _sharedFlow?.emit(event)
    }

    fun input(event: Event) {
        viewModelScope.launch {
            if (needDelayForLifecycleState) delayForLifecycleState().collect { onHandle(event) }
            else onHandle(event)
        }
    }

    protected open fun isSuccess(result: HttpData<*>, httpData: HttpData<*>): Boolean {
        if (!httpData.isSuccess) {
            result.isSuccess = false
            result.msg = httpData.msg
            return false
        }
        result.isSuccess = true
        return true
    }

    protected open fun isSuccess(result: HttpData<*>, any: Any?): Boolean {
        if (any == null) {
            result.isSuccess = false
            result.msg = "没有数据"
            return false
        }
        result.isSuccess = true
        return true
    }

    private val needDelayForLifecycleState
        get() = delayMap.isNotEmpty()

    protected open suspend fun onHandle(event: Event) {}

    private fun delayForLifecycleState() = flow {
        delay(1)
        emit(true)
    }

    companion object {
        private const val DEFAULT_QUEUE_LENGTH = 10
    }
}